/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.isfd.service.impl;


import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.comac.ins.common.core.constant.CommonConstant;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.core.utils.StringUtils;
import com.comac.ins.common.excel.utils.ExcelUtil;
import com.comac.ins.common.json.utils.JsonUtils;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.isfd.config.IsfdModelManagementOriginalPartConfig;
import com.comac.ins.isfd.constant.enums.*;
import com.comac.ins.isfd.domain.IsfdModelManagementCard;
import com.comac.ins.isfd.domain.IsfdModelManagementNecessaryItems;
import com.comac.ins.isfd.domain.IsfdModelManagementPart;
import com.comac.ins.isfd.domain.bo.*;
import com.comac.ins.isfd.domain.bo.query.IsfdModelManagementPartQueryBo;
import com.comac.ins.isfd.domain.bomt.IsfdDetailOriginalV2BomVo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.mapper.IsfdModelManagementCardMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementNecessaryItemsMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementPartMapper;
import com.comac.ins.isfd.mapper.IsfdModelManagementTaskMapper;
import com.comac.ins.isfd.service.IIsfdModelManagementPartService;
import com.comac.ins.isfd.service.IIsfdModelManagementStructureDefinitionTreeService;
import com.comac.ins.isfd.util.CompressUtils;
import com.comac.ins.isfd.util.FileUtils;
import com.comac.ins.isfd.util.RegexMatcher;
import com.comac.ins.system.service.ISysDictDataService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 模型管理零件Service业务层处理
 *
 * @author Lion Li
 * @date 2024-08-14
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class IsfdModelManagementPartServiceImpl implements IIsfdModelManagementPartService {

    @Autowired
    private IsfdModelManagementPartMapper baseMapper;

    @Autowired
    private ISysDictDataService iSysDictDataService;

    @Autowired
    private IsfdModelManagementNecessaryItemsMapper isfdModelManagementNecessaryItemsMapper;

    @Autowired
    private IIsfdModelManagementStructureDefinitionTreeService iIsfdModelManagementStructureDefinitionTreeService;

    @Autowired
    private IsfdModelManagementOriginalPartConfig isfdModelManagementOriginalPartConfig;

    @Autowired
    private IsfdModelManagementCardMapper isfdModelManagementCardMapper;

    @Autowired
    protected ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private IsfdModelManagementTaskMapper isfdModelManagementTaskMapper;

    public static final Integer BATCH_NUMBER_SIZE = 10;

    private static final int CORE_NUM;

    static {
        CORE_NUM = Math.max(2, Runtime.getRuntime().availableProcessors() / 2);
    }

    private static final String DEFAULT_MODEL = "default_model.bdf";
    private static final String DEFAULT_SECTION = "default_section.bdf";


    @Override
    public List<String> getComponentBySection(String modelNumber, String batchNumber, String sectionNumber, Boolean necessaryItemsFlag) {
        List<IsfdModelManagementPart> partsVo = baseMapper.selectList(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(IsfdModelManagementPart::getModelNumber, modelNumber)
            .eq(IsfdModelManagementPart::getBatchNumber, batchNumber)
            .eq(IsfdModelManagementPart::getSectionNumber, sectionNumber)
            .eq(IsfdModelManagementPart::getFileType, PartFileTypeEnum.PART.getValue()));
        if (CollectionUtils.isEmpty(partsVo)) {
            return new ArrayList<>();
        }

        Set<String> componentNumberList = partsVo.stream()
            .map(IsfdModelManagementPart::getComponentNumber)
            .collect(Collectors.toSet());

        // 是否要帮忙筛选
        List<String> resultList = new ArrayList<>();
        if (necessaryItemsFlag != null && necessaryItemsFlag) {
            for (String componentNumber : componentNumberList) {
                Long count = isfdModelManagementNecessaryItemsMapper.selectCount(new LambdaQueryWrapper<IsfdModelManagementNecessaryItems>()
                    .eq(IsfdModelManagementNecessaryItems::getModelNumber, modelNumber)
                    .eq(IsfdModelManagementNecessaryItems::getBatchNumber, batchNumber)
                    .eq(IsfdModelManagementNecessaryItems::getComponentNumber, componentNumber));
                if (count > 0L) {
                    resultList.add(componentNumber);
                }
            }
        } else {
            resultList = componentNumberList.stream().toList();
        }
        return resultList;
    }

    @Override
    public List<IsfdModelManagementPartOuterVo> selectPart(List<IsfdModelManagementSelectPartBo> selectList) {
        Set<String> modelNumberSet = selectList.stream().map(IsfdModelManagementSelectPartBo::getModelNumber).collect(Collectors.toSet());
        Set<String> batchNumberSet = selectList.stream().map(IsfdModelManagementSelectPartBo::getBatchNumber).collect(Collectors.toSet());
        Set<String> sectionNumberSet = selectList.stream().map(IsfdModelManagementSelectPartBo::getSectionNumber).collect(Collectors.toSet());
        Set<String> componentNumberSet = selectList.stream().map(IsfdModelManagementSelectPartBo::getComponentNumber).collect(Collectors.toSet());
        return baseMapper.selectPart(modelNumberSet, batchNumberSet, sectionNumberSet, componentNumberSet);
    }

    /**
     * 查询模型管理零件
     *
     * @param id 主键
     * @return 模型管理零件
     */
    @Override
    public IsfdModelManagementPartVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    @Override
    public List<IsfdModelManagementStructureDefinitionTreeNodeVo> listTree() {
        // 查询总的树结构 机型-部段
        List<IsfdModelManagementStructureDefinitionTreeNodeVo> treeNodeVos = iIsfdModelManagementStructureDefinitionTreeService.queryListTree();

        // 找出所有为部段的叶子节点，并给封装好相应的组件数据，形成 机型-批次-部段-组件的结构
        for (IsfdModelManagementStructureDefinitionTreeNodeVo treeNode : treeNodeVos) {
            findLeafNodesRecursive(treeNode);
        }
        return treeNodeVos;
    }

    /**
     * 找叶子节点 ，并在叶子节点进行再封装
     *
     * @param node 输入的树
     */
    public void findLeafNodesRecursive(IsfdModelManagementStructureDefinitionTreeNodeVo node) {
        if (node == null) {
            return;
        }
        if (CollectionUtils.isEmpty(node.getChildren()) && IsfdStructureDefinitionTreeLevelEnum.SECTION.getValue().equals(node.getLevel())) {
            // 当前节点没有子节点，因此它是叶子节点
            if (node.getParentId() != 0) {
                // 找到批次节点
                IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryById(node.getParentId());
                // 找到机型节点
                IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryById(batchVo.getParentId());
                List<String> fileTypeList = new ArrayList<>();
                fileTypeList.add(PartFileTypeEnum.PART.getValue());
                fileTypeList.add(PartFileTypeEnum.FASTENER.getValue());
                List<IsfdModelManagementPart> partList = baseMapper.selectList(new LambdaQueryWrapper<IsfdModelManagementPart>()
                    .eq(IsfdModelManagementPart::getModelNumber, modelVo.getMark())
                    .eq(IsfdModelManagementPart::getBatchNumber, batchVo.getMark())
                    .eq(IsfdModelManagementPart::getSectionNumber, node.getMark())
                    .eq(IsfdModelManagementPart::getFileLevel, PartFileLevelEnum.COMPONENT.getValue())
                    .in(IsfdModelManagementPart::getFileType, fileTypeList));
                Set<String> componentNumberList = null;
                if (CollectionUtils.isNotEmpty(partList)) {
                    // 去重
                    componentNumberList = new HashSet<>();
                    for (IsfdModelManagementPart part : partList) {
                        componentNumberList.add(part.getComponentNumber());
                    }
                    // 封装部件下的组件
                    List<IsfdModelManagementStructureDefinitionTreeNodeVo> children = new ArrayList<>();
                    for (String componentNumber : componentNumberList) {
                        IsfdModelManagementStructureDefinitionTreeNodeVo child = new IsfdModelManagementStructureDefinitionTreeNodeVo();
                        child.setParentId(node.getId());
                        child.setMark(componentNumber);
                        child.setName(componentNumber);
                        child.setTaskDefault(node.getTaskDefault());
                        child.setLevel(IsfdStructureDefinitionTreeLevelEnum.COMPONENT.getValue());
                        children.add(child);
                    }
                    node.setChildren(children);
                }
            }
        } else {
            // 遍历子节点
            if (CollectionUtils.isNotEmpty(node.getChildren())) {
                for (IsfdModelManagementStructureDefinitionTreeNodeVo child : node.getChildren()) {
                    findLeafNodesRecursive(child);
                }
            }
        }
    }


    @Override
    public TableDataInfo<IsfdModelManagementPartOuterVo> queryPageList(IsfdModelManagementPartQueryBo bo) {
        String queryMode = bo.getQueryMode();
        QueryWrapper<IsfdModelManagementPart> wrapper = Wrappers.query();
        List<String> fileTypeList = new ArrayList<>();
        fileTypeList.add(PartFileTypeEnum.PART.getValue());
        fileTypeList.add(PartFileTypeEnum.FASTENER.getValue());
        wrapper.eq(StringUtils.isNotBlank(bo.getModelNumber()), "model_number", bo.getModelNumber())
            .eq(StringUtils.isNotBlank(bo.getBatchNumber()), "batch_number", bo.getBatchNumber())
            .eq(StringUtils.isNotBlank(bo.getSectionNumber()), "section_number", bo.getSectionNumber())
            .eq(StringUtils.isNotBlank(bo.getComponentNumber()), "component_number", bo.getComponentNumber())
            .in("file_type", fileTypeList);
        if (queryMode.equals(QueryModeEnum.EQ.getValue())) {
            wrapper.eq(StringUtils.isNotBlank(bo.getPartNumber()), "part_number", bo.getPartNumber())
                .eq(StringUtils.isNotBlank(bo.getName()), "name", bo.getName())
                .eq(StringUtils.isNotBlank(bo.getVersionNumber()), "version_number", bo.getVersionNumber())
                .orderByDesc("create_time");
        } else {
            wrapper.like(StringUtils.isNotBlank(bo.getPartNumber()), "part_number", bo.getPartNumber())
                .like(StringUtils.isNotBlank(bo.getName()), "name", bo.getName())
                .eq(StringUtils.isNotBlank(bo.getVersionNumber()), "version_number", bo.getVersionNumber())
                .orderByDesc("create_time");
        }
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(bo.getPageNum());
        pageQuery.setPageSize(bo.getPageSize());
        Page<IsfdModelManagementPartOuterVo> result = baseMapper.queryPageList(pageQuery.build(), wrapper);
        result.getRecords().forEach(outer -> {
            outer.getVersionVoList().forEach(inner -> {
                inner.setPartNumber(outer.getPartNumber());
            });
        });
        return TableDataInfo.build(result);
    }

    @Override
    public List<IsfdModelManagementPartVo> queryList(List<Long> partIdList) {
        return baseMapper.selectVoBatchIds(partIdList);
    }

    @Override
    public IsfdModelManagementPartOuterVo detail(String modelNumber,
                                                 String batchNumber,
                                                 String sectionNumber,
                                                 String componentNumber,
                                                 String partNumber) {
        IsfdModelManagementPartOuterVo vo = baseMapper.queryByPartNumber(modelNumber, batchNumber, sectionNumber, componentNumber, partNumber);
        IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null);
        IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null);
        IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
        vo.setModelName(modelVo.getName());
        vo.setSectionName(sectionVo.getName());
        vo.setBatchName(batchVo.getName());
        return vo;
    }

    /**
     * 查询符合条件的模型管理零件列表
     *
     * @param bo 查询条件
     * @return 模型管理零件列表
     */
    @Override
    public List<IsfdModelManagementPartVo> queryList(IsfdModelManagementPartBo bo) {
        LambdaQueryWrapper<IsfdModelManagementPart> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<IsfdModelManagementPart> buildQueryWrapper(IsfdModelManagementPartBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<IsfdModelManagementPart> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getComponentNumber()), IsfdModelManagementPart::getComponentNumber, bo.getComponentNumber());
        lqw.like(StringUtils.isNotBlank(bo.getPartName()), IsfdModelManagementPart::getPartName, bo.getPartName());
        lqw.eq(StringUtils.isNotBlank(bo.getVersionNumber()), IsfdModelManagementPart::getVersionNumber, bo.getVersionNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getPartNumber()), IsfdModelManagementPart::getPartNumber, bo.getPartNumber());
        lqw.eq(bo.getFileSize() != null, IsfdModelManagementPart::getFileSize, bo.getFileSize());
        lqw.eq(StringUtils.isNotBlank(bo.getModelNumber()), IsfdModelManagementPart::getModelNumber, bo.getModelNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getBatchNumber()), IsfdModelManagementPart::getBatchNumber, bo.getBatchNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getSectionNumber()), IsfdModelManagementPart::getSectionNumber, bo.getSectionNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getModelIndex()), IsfdModelManagementPart::getModelIndex, bo.getModelIndex());
        lqw.eq(StringUtils.isNotBlank(bo.getSectionIndex()), IsfdModelManagementPart::getSectionIndex, bo.getSectionIndex());
        lqw.eq(StringUtils.isNotBlank(bo.getComponentIndex()), IsfdModelManagementPart::getComponentIndex, bo.getComponentIndex());
        lqw.eq(StringUtils.isNotBlank(bo.getIndexPath()), IsfdModelManagementPart::getIndexPath, bo.getIndexPath());
        lqw.like(StringUtils.isNotBlank(bo.getFileName()), IsfdModelManagementPart::getFileName, bo.getFileName());
        lqw.eq(StringUtils.isNotBlank(bo.getFileLevel()), IsfdModelManagementPart::getFileLevel, bo.getFileLevel());
        lqw.eq(StringUtils.isNotBlank(bo.getFileType()), IsfdModelManagementPart::getFileType, bo.getFileType());
        return lqw;
    }


    @Override
    public List<IsfdModelManagementPartVo> checkImport(MultipartFile multipartFile, String modelNumber, String batchNumber, String indexFileName) {
        StopWatch stopWatch = StopWatch.createStarted();
        log.info("整机导入-规则检查开始 .");
        // 强度数模清单校验
        if (!isfdModelManagementOriginalPartConfig.checkStrengthBomImport(modelNumber, batchNumber)) {
            throw new BaseException("请先到「标准装机清单」中选择该机型(" + modelNumber + ")及批次(" + batchNumber + ")数据生成”强度数模清单“。");
        }
        //压缩文件原名
        String compressFileName = multipartFile.getOriginalFilename();
        //获取文件名
        String fileName = StringUtils.substringBeforeLast(compressFileName, ".");
        //获取文件后缀
        String fileSuffix = StringUtils.substringAfterLast(compressFileName, ".");

        //multipartFile 转file
        File file = FileUtils.multiPartFileToFile(multipartFile);
        stopWatch.stop();
        log.info("0.multipartFile 转file ,耗时：{}", stopWatch.getTime());
        stopWatch.reset();
        stopWatch.start();

        List<String> allPath = null;
        List<IsfdModelManagementPartVo> voList = null;
        try {
            String tempPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
                CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
            if (StringUtils.isBlank(tempPath)) {
                throw new BaseException("字典中没有找到文件存储地址的相关配置。");
            }
            // 临时文件目录
            File tempPathDir = new File(RegexMatcher.getDataPrePath(tempPath, batchNumber));
            if (!tempPathDir.exists()) {
                tempPathDir.mkdirs();
            }

            //1.解压文件，解析出总的List<Path> allPath
            if (fileSuffix.equalsIgnoreCase(CompressionTypeEnum.ZIP.getValue())) {
                allPath = CompressUtils.extractZipReturnPathList(file, tempPathDir, System.getProperty("sun.jnu.encoding"), Boolean.TRUE);
            } else if (fileSuffix.equalsIgnoreCase(CompressionTypeEnum.RAR.getValue())) {
                allPath = CompressUtils.extractRarReturnPathList(file, tempPathDir, Boolean.TRUE);
            } else {
                throw new BaseException("不支持该压缩文件类型，请确认是导入压缩包类型后再试。");
            }
            if (CollectionUtils.isEmpty(allPath)) {
                throw new BaseException("解压失败");
            }
            stopWatch.stop();
            log.info("1.解压文件，解析出总的List<Path> allPath ,耗时：{}", stopWatch.getTime());
            stopWatch.reset();
            stopWatch.start();

            //2.校验机型和部段 并进行过滤
            List<String> newAllPath = checkAndAddSection(modelNumber, batchNumber, allPath, tempPath);

            stopWatch.stop();
            log.info("2.校验机型和部段 并进行过滤 ,耗时：{}", stopWatch.getTime());
            stopWatch.reset();
            stopWatch.start();

            //3.找索引文件，解析索引文件里的路径，放到List<Path> indexPath（从allPath里去找文件，找到后读取文件，截取include，最终是分三层，机型、部段、组件 ）
            voList = analyzeFileIndexAndReturnVoListPartitions(newAllPath, fileName, tempPath, modelNumber, batchNumber, indexFileName);
            stopWatch.stop();
            log.info("3.找索引文件，解析索引文件里的路径 ,耗时：{}", stopWatch.getTime());
        } catch (Exception e) {
            log.error("解压失败", e);
            if (e instanceof BaseException) {
                throw (BaseException) e;
            }
            throw new BaseException("解压失败");
        } finally {
            if (file != null) {
                file.delete();
            }
        }
        return voList;
    }


    @Override
    public IsfdModelManagementConfirmImportPartVo confirmImportPartitions(IsfdModelManagementPartConfirmImportBo param, LoginUser loginUser) {
        List<IsfdModelManagementPartBo> boList = param.getBoList();
        StopWatch stopWatch = StopWatch.createStarted();
        log.info("确认导入开始 .");

        IsfdModelManagementConfirmImportPartVo resultVo = new IsfdModelManagementConfirmImportPartVo();
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        long importNumber = 0;
        long updatedImportNumber = 0;
        long notImportNumber = 0;
        long failImportNumber = 0;
        String tempPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
        String targetPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_DATA_PREFIX);
        if (StringUtils.isBlank(tempPath) || StringUtils.isBlank(targetPath)) {
            throw new BaseException("字典中没有找到文件存储地址的相关配置。");
        }
        if (StringUtils.isBlank(param.getIsCover())) {
            throw new BaseException("参数异常，整机覆盖导入标识为空！");
        }
        // 筛选出 part和fastener类型的数据
        List<IsfdModelManagementPartBo> resultPartBoList = boList.stream().filter(bo -> PartFileTypeEnum.checkPartAndFastener(bo.getFileType())).toList();
        if (CollectionUtils.isEmpty(resultPartBoList)) {
            throw new BaseException("没有可导入的零件数据，请确认后重试！");
        }
        // 查询 机型
        String modelNumber = resultPartBoList.get(0).getModelNumber();
        String modelName = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null).getMark();

        // 查询 批次
        String batchNumber = resultPartBoList.get(0).getBatchNumber();
        String batchName = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null).getMark();

        // 查询 部段
        Map<String, IsfdModelManagementStructureDefinitionTreeVo> sectionMap = new HashMap<>();

        stopWatch.stop();
        log.info("1.零件筛选出来，准备进入循环处理数据,耗时：{}", stopWatch.getTime());
        stopWatch.reset();
        stopWatch.start();
        // 数据分批
        List<List<IsfdModelManagementPartBo>> partitions = new ArrayList<>();
        int batchSize = resultPartBoList.size() / BATCH_NUMBER_SIZE;
        if (batchSize == 0) {
            partitions.add(resultPartBoList);
        } else {
            for (int i = 0; i < resultPartBoList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, resultPartBoList.size());
                partitions.add(resultPartBoList.subList(i, end));
            }
        }

        ExecutorService executor = Executors.newFixedThreadPool(BATCH_NUMBER_SIZE);
        List<Future<IsfdModelManagementConfirmImportPartVo>> futures = new ArrayList<>();
        Long userId = loginUser.getUserId();
        Long deptId = loginUser.getDeptId();

        //删除零件和任务数据
        if (PartImportCoverEnum.COVER.getValue().equals(param.getIsCover())) {
            HashMap<String, Object> deleteMap = new HashMap<>();
            deleteMap.put("model_number", modelNumber);
            deleteMap.put("batch_number", batchNumber);
            baseMapper.deleteByMap(deleteMap);
            isfdModelManagementTaskMapper.deleteByMap(deleteMap);
        }
        // 循环分批启用线程处理数据
        for (List<IsfdModelManagementPartBo> partition : partitions) {
            final List<IsfdModelManagementPartBo> finalPartition = partition;
            Future<IsfdModelManagementConfirmImportPartVo> future = executor.submit(() -> {
                try {
                    //是否覆盖导入
                    if (PartImportCoverEnum.NOT_COVER.getValue().equals(param.getIsCover())) {
                        return confirmImportDealData(finalPartition, sectionMap, modelNumber, modelName,
                            batchNumber, batchName, tempPath, targetPath, userId, deptId);
                    } else {
                        return coverConfirmImportDealData(finalPartition, sectionMap, modelNumber, modelName,
                            batchNumber, batchName, tempPath, targetPath, userId, deptId);
                    }
                } catch (Exception e) {
                    log.error("分批次确认导入失败", e);
                    throw new BaseException("分批次确认导入失败");
                }
            });
            futures.add(future);
        }

        try {
            executor.shutdown();
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (Exception e) {
            log.error("分批次确认导入等待失败", e);
            throw new BaseException("分批次确认导入等待失败");
        }

        for (Future<IsfdModelManagementConfirmImportPartVo> future : futures) {
            try {
                IsfdModelManagementConfirmImportPartVo result = future.get();
                partVoList.addAll(result.getPartVoList());
                importNumber = importNumber + result.getImportNumber();
                updatedImportNumber = updatedImportNumber + result.getUpdatedImportNumber();
                notImportNumber = notImportNumber + result.getNotImportNumber();
                failImportNumber = failImportNumber + result.getFailImportNumber();
            } catch (Exception e) {
                log.error("分批次确认导入合并失败", e);
                throw new BaseException("分批次确认导入合并失败");
            }
        }
        resultVo.setPartVoList(partVoList);
        resultVo.setImportNumber(importNumber);
        resultVo.setFailImportNumber(failImportNumber);
        resultVo.setNotImportNumber(notImportNumber);
        resultVo.setUpdatedImportNumber(updatedImportNumber);

        stopWatch.stop();
        log.info("2.零件数据循环处理完毕,耗时：{}", stopWatch.getTime());
        stopWatch.reset();
        stopWatch.start();

        // 异步 处理非零件的数据，索引、拓展
        threadPoolTaskExecutor.execute(() -> {
            List<IsfdModelManagementPartBo> resultOtherBoList = boList.stream().filter(bo -> !PartFileTypeEnum.checkPartAndFastener(bo.getFileType())).toList();
            for (IsfdModelManagementPartBo bo : resultOtherBoList) {
                IsfdModelManagementPart po = MapstructUtils.convert(bo, IsfdModelManagementPart.class);
                String indexPath = bo.getIndexPath();
                String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, batchNumber, indexPath, bo.getSortie());
                String newIndexPath = RegexMatcher.getDataPath(targetPath, batchNumber, indexPath);
                FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);
                po.setVersionNumber(null);
                po.setPartNumber(null);
                po.setCreateDept(deptId);
                if (bo.getId() != null) {
                    po.setUpdateBy(userId);
                    baseMapper.updateById(po);
                } else {
                    po.setCreateBy(userId);
                    po.setUpdateBy(userId);
                    baseMapper.insert(po);
                }
            }
        });

        stopWatch.stop();
        log.info("3.非零件数据循环处理完毕,耗时：{}", stopWatch.getTime());
        return resultVo;
    }

    @Transactional
    @Override
    public IsfdModelManagementPartVo update(IsfdModelManagementUpdateImportPartBo bo) {
        // 判断存在否
        IsfdModelManagementPart isfdModelManagementPart = baseMapper.selectById(bo.getId());
        if (isfdModelManagementPart == null) {
            throw new BaseException("零件不存在，请确认后重试！");
        }
        // 幂等判断
        IsfdModelManagementPart targetPo = baseMapper.selectOne(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(StringUtils.isNotBlank(isfdModelManagementPart.getModelNumber()), IsfdModelManagementPart::getModelNumber, isfdModelManagementPart.getModelNumber())
            .eq(StringUtils.isNotBlank(isfdModelManagementPart.getBatchNumber()), IsfdModelManagementPart::getBatchNumber, isfdModelManagementPart.getBatchNumber())
            .eq(StringUtils.isNotBlank(isfdModelManagementPart.getSectionNumber()), IsfdModelManagementPart::getSectionNumber, isfdModelManagementPart.getSectionNumber())
            .eq(StringUtils.isNotBlank(isfdModelManagementPart.getComponentNumber()), IsfdModelManagementPart::getComponentNumber, isfdModelManagementPart.getComponentNumber())
            .eq(IsfdModelManagementPart::getPartNumber, bo.getPartNumber())
            .eq(IsfdModelManagementPart::getVersionNumber, bo.getVersionNumber()));
        if (targetPo != null) {
            if (!targetPo.getId().equals(bo.getId())) {
                throw new BaseException("修改的零件名称或者版本号在库中已存在，请重命名后重试！");
            }
            throw new BaseException("当前修改操作没有做任何改动，请重命名后重试！");
        }
        String tempPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
        String targetPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_DATA_PREFIX);
        if (StringUtils.isBlank(tempPath) || StringUtils.isBlank(targetPath)) {
            throw new BaseException("字典中没有找到文件存储地址的相关配置。");
        }
        String partNumber = bo.getPartNumber();
        String versionNumber = bo.getVersionNumber();
        String partName = partNumber + "_" + versionNumber + ".bdf";
        // 把文件拷贝一份到新路径下
        isfdModelManagementPart.setPartName(partName);
        String indexPath = bo.getIndexPath();
        String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, isfdModelManagementPart.getBatchNumber(), isfdModelManagementPart.getIndexPath(), bo.getSortie());
        isfdModelManagementPart.setIndexPath(StringUtils.substringBeforeLast(indexPath, "/") + "/" + isfdModelManagementPart.getPartName());
        String newIndexPath = RegexMatcher.getDataPath(targetPath, isfdModelManagementPart.getBatchNumber(), isfdModelManagementPart.getIndexPath());
        FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.FALSE);
        // 改DB数据
        if (StringUtils.isNotBlank(bo.getComponentIndex())
            && bo.getFileLevel().equals(PartFileLevelEnum.COMPONENT.getValue())
            && bo.getComponentIndex().equals(bo.getIndexPath())) {
            isfdModelManagementPart.setComponentIndex(isfdModelManagementPart.getIndexPath());
        }
        if (StringUtils.isNotBlank(bo.getSectionIndex())
            && bo.getFileLevel().equals(PartFileLevelEnum.SECTION.getValue())
            && bo.getSectionIndex().equals(bo.getIndexPath())) {
            isfdModelManagementPart.setSectionIndex(isfdModelManagementPart.getIndexPath());
        }
        if (StringUtils.isNotBlank(bo.getModelIndex())
            && bo.getFileLevel().equals(PartFileLevelEnum.MODEL.getValue())
            && bo.getModelIndex().equals(bo.getIndexPath())) {
            isfdModelManagementPart.setModelIndex(isfdModelManagementPart.getIndexPath());
        }

        isfdModelManagementPart.setPartName(partName);
        isfdModelManagementPart.setPartNumber(partNumber);
        isfdModelManagementPart.setVersionNumber(versionNumber);
        isfdModelManagementPart.setFileName(partName);
        isfdModelManagementPart.setId(null);
        baseMapper.insert(isfdModelManagementPart);

        // 返回给前端
        IsfdModelManagementPartVo isfdModelManagementPartVo = MapstructUtils.convert(isfdModelManagementPart, IsfdModelManagementPartVo.class);
        isfdModelManagementPartVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
        isfdModelManagementPartVo.setImportOperationTags(ImportOperationTagsEnum.UPDATED.getValue());
        return isfdModelManagementPartVo;
    }

    @Override
    public Boolean cancelImport(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Boolean.TRUE;
        }
        baseMapper.deleteBatchIds(ids);
        return Boolean.TRUE;
    }

    @Override
    public void bomExport(String modelNumber, HttpServletResponse response) {
        // 查询部段
        IsfdModelManagementStructureDefinitionTreeVo modelTreeVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null);
        if (modelTreeVo == null) {
            throw new BaseException("机型定义不存在，请确认后重试！");
        }

        // 获取要导出的原始数据
        List<IsfdModelManagementPartVo> partVos = baseMapper.selectVoList(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(IsfdModelManagementPart::getModelNumber, modelNumber)
            .and(qw -> qw.eq(IsfdModelManagementPart::getFileType, PartFileTypeEnum.FASTENER.getValue()).or().eq(IsfdModelManagementPart::getFileType, PartFileTypeEnum.PART.getValue())));
        if (CollectionUtils.isEmpty(partVos)) {
            throw new BaseException("机型下无零件，不能导出BOM文件！");
        }


        List<IsfdModelManagementPartExportVo> isfdModelManagementPartExportVoList = MapstructUtils.convert(partVos, IsfdModelManagementPartExportVo.class);
        // 封装 机型名称、批次名称和部段名称
        Map<String, String> batchMap = new HashMap<>();
        Map<String, String> sectionMap = new HashMap<>();
        for (IsfdModelManagementPartExportVo vo : isfdModelManagementPartExportVoList) {
            String batchNumber = vo.getBatchNumber();
            String batchKey = modelNumber + "::" + batchNumber;
            if (batchMap.get(batchKey) == null) {
                IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService
                    .queryOneByQueryIndex(modelNumber, batchNumber, null);
                batchMap.put(batchKey, batchVo.getName());
                vo.setBatchName(batchVo.getName());
            } else {
                vo.setBatchName(batchMap.get(batchKey));
            }

            String sectionNumber = vo.getSectionNumber();
            String sectionKey = modelNumber + "::" + batchNumber + "::" + sectionNumber;
            if (sectionMap.get(sectionKey) == null) {
                IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService
                    .queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
                sectionMap.put(sectionKey, sectionVo.getName());
                vo.setSectionName(sectionVo.getName());
            } else {
                vo.setSectionName(sectionMap.get(sectionKey));
            }

            vo.setModelName(vo.getModelNumber());
        }

        // 分组
        Map<String, List<IsfdModelManagementPartExportVo>> groupSectionNumberMap = isfdModelManagementPartExportVoList.stream()
            .collect(Collectors.groupingBy(IsfdModelManagementPartExportVo::getSectionName));

        // 封装导出的data
        Map<String, Object> data = new HashMap<>();
        for (String sectionName : groupSectionNumberMap.keySet()) {
            data.put(sectionName, groupSectionNumberMap.get(sectionName));
        }
        ExcelUtil.exportWithOutTemplateMultiList(data, modelTreeVo.getName(), IsfdModelManagementPartExportVo.class, response);
    }


    @Override
    public IsfdModelManagementPartVo singleImport(IsfdModelManagementPartBo partBo) {
        // 存磁盘，temp目录拷贝到data目录
        String tempPrePath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
        if (StringUtils.isBlank(tempPrePath)) {
            throw new BaseException("字典中没有找到文件存储地址的相关配置。");
        }
        String dataPrePath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_DATA_PREFIX);
        if (StringUtils.isBlank(tempPrePath)) {
            throw new BaseException("字典中没有找到文件存储地址的相关配置。");
        }
        String indexPath = partBo.getIndexPath();
        String batchNumber = partBo.getBatchNumber();
        String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPrePath, batchNumber, indexPath, partBo.getSortie());
        String newIndexPath = RegexMatcher.getDataPath(dataPrePath, batchNumber, indexPath);
        // 写入磁盘
        FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);

        // 存db
        IsfdModelManagementPart po = MapstructUtils.convert(partBo, IsfdModelManagementPart.class);
        baseMapper.insert(po);
        return MapstructUtils.convert(po, IsfdModelManagementPartVo.class);
    }

    @Override
    public IsfdModelManagementPartVo checkSingleImport(MultipartFile multipartFile, String modelNumber, String batchNumber, String sectionNumber, String componentNumber) {
        // 1.基础数据处理和校验
        // 强度数模清单校验
        if (!isfdModelManagementOriginalPartConfig.checkStrengthBomImport(modelNumber, batchNumber)) {
            throw new BaseException("请先到「标准装机清单」中选择该机型(" + modelNumber + ")及批次(" + batchNumber + ")数据生成”强度数模清单“。");
        }
        // 原始数据处理
        String compressFileName = multipartFile.getOriginalFilename();
        // 获取文件名
        String fileName = StringUtils.substringBeforeLast(compressFileName, ".");
        // 获取文件后缀
        String fileSuffix = StringUtils.substringAfterLast(compressFileName, ".");
        if (!Arrays.stream(CommonConstant.BDF_TYPE_LIST).toList().contains(fileSuffix)) {
            throw new BaseException("上传文件类型不是bdf，请确认后重试！");
        }
        // 校验文件名格式
        String[] partNumberAndVersion = RegexMatcher.getPartNumber(fileName);
        PartFileTypeEnum partFileTypeEnum = RegexMatcher.matchesPartFileType(partNumberAndVersion[0], null);
        if (!PartFileTypeEnum.checkPartAndFastener(partFileTypeEnum.getValue())) {
            throw new BaseException("文件名格式不正确，可上传文件类型有：紧固件或者零件。\n 文件名格式为 R_开头、Gxx或者Gxx.x结尾（x代表数字，比如：R_5333C22000G25_A1.bdf、5211C01001G71_C.bdf 或者 5211C01001G71.2_C.bdf)");
        }
        // 查询机型
        IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null);
        if (modelVo == null) {
            throw new BaseException("选择的机型不存在，请确认后重试！");
        }

        // 查询批次
        IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null);
        if (batchVo == null) {
            throw new BaseException("选择的批次不存在，请确认后重试！");
        }

        // 查询部段
        IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
        if (sectionVo == null) {
            throw new BaseException("选择的部段不存在，请确认后重试！");
        }
        // 幂等校验
        IsfdModelManagementPartVo uniquePartVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, componentNumber, compressFileName);
        if (uniquePartVo != null) {
            throw new BaseException("上传的零件已存在，请修改零件后重试！");
        }
        // 找组件位置
        List<IsfdModelManagementPart> partsVoList = baseMapper.selectList(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(IsfdModelManagementPart::getModelNumber, modelNumber)
            .eq(IsfdModelManagementPart::getBatchNumber, batchNumber)
            .eq(IsfdModelManagementPart::getSectionNumber, sectionNumber)
            .eq(IsfdModelManagementPart::getComponentNumber, componentNumber)
            .eq(IsfdModelManagementPart::getFileType, PartFileTypeEnum.PART.getValue()));
        IsfdModelManagementPart brotherPart = partsVoList.get(0);
        if (CollectionUtils.isEmpty(partsVoList)) {
            throw new BaseException("未找到对应零件的组件信息，请确认后重试！");
        }

        IsfdModelManagementPartVo partVo = new IsfdModelManagementPartVo();
        // 2. 处理磁盘
        // multipartFile 转file
        File file = FileUtils.multiPartFileToFile(multipartFile);
        try {
            String tempPrePath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
                CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
            if (StringUtils.isBlank(tempPrePath)) {
                throw new BaseException("字典中没有找到文件存储地址的相关配置。");
            }
            String brotherPartIndexPath = brotherPart.getIndexPath();
            String indexPath = StringUtils.substringBeforeLast(brotherPartIndexPath, "/") + "/" + compressFileName;
            String filePath = RegexMatcher.rebuildOldDataPath(tempPrePath, batchNumber, indexPath, brotherPart.getSortie());
            // 写入磁盘 temp目录
            FileUtils.copyOrMoveFile(file.getPath(), filePath, Boolean.TRUE);

            // 3.封装返回
            partVo.setModelNumber(modelNumber);
            partVo.setSortie(brotherPart.getSortie());
            partVo.setBatchNumber(batchNumber);
            partVo.setSectionNumber(sectionNumber);
            partVo.setComponentNumber(componentNumber);
            partVo.setModelIndex(brotherPart.getModelIndex());
            partVo.setSectionIndex(brotherPart.getSectionIndex());
            partVo.setComponentIndex(brotherPart.getComponentIndex());
            partVo.setIndexPath(indexPath);
            partVo.setPartName(compressFileName);
            partVo.setPartNumber(RegexMatcher.getPartNumber(compressFileName)[0]);
            partVo.setVersionNumber(RegexMatcher.getPartNumber(compressFileName)[1]);
            partVo.setFileSize(Files.size(Path.of(filePath)));
            partVo.setFileName(compressFileName);
            partVo.setFileLevel(PartFileLevelEnum.COMPONENT.getValue());
            partVo.setFileType(partFileTypeEnum.getValue());
            partVo.setModelName(modelVo.getName());
            partVo.setSectionName(sectionVo.getName());
            // 封装原始零件信息
            buildOriginalDetailToPart(partVo, StringUtils.substringBeforeLast(partVo.getPartNumber(), "."));

        } catch (Exception e) {
            log.error("单个零件上传-规则检查失败", e);
            if (e instanceof BaseException) {
                throw new BaseException(e.getMessage());
            }
            throw new BaseException("单个零件上传-规则检查失败");
        } finally {
            if (file != null) {
                file.delete();
            }
        }

        return partVo;
    }

    @Override
    public Long insert(IsfdModelManagementPartBo isfdModelManagementPartBo) {
        // 增加校验
        checkPartInfo(isfdModelManagementPartBo);

        IsfdModelManagementPart isfdModelManagementPart = MapstructUtils.convert(isfdModelManagementPartBo, IsfdModelManagementPart.class);
        baseMapper.insert(isfdModelManagementPart);
        return isfdModelManagementPart.getId();
    }

    private void checkPartInfo(IsfdModelManagementPartBo partBo) {
        Map<String, String> versionMaps = getExistingVersions(partBo);
        String newVersionNumber = partBo.getVersionNumber();
        // 检查版本号是否符合规则，版本号规则：纯字母或字母加数字
        String versionPattern = "^[a-zA-Z]+[a-zA-Z0-9]*$";
        if (!newVersionNumber.matches(versionPattern)) {
            log.error("版本号格式错误！版本号必须是纯字母或字母加数字的组合：{}", newVersionNumber);
            throw new BaseException(
                "版本号格式错误！版本号必须是纯字母或字母加数字的组合：" + newVersionNumber
            );
        }
        // 是否已有版本号
        if (versionMaps.containsKey(partBo.getVersionNumber())) {
            log.error("新增版本号冲突！当前版本号：{} 已存在于历史版本中！", newVersionNumber);
            throw new BaseException(
                "新增版本号冲突！当前版本号：" + newVersionNumber + " 已存在于历史版本中！"
            );
        }
    }


    public Map<String, String> getExistingVersions(IsfdModelManagementPartBo partBo) {
        String partIndex = String.join("/", partBo.getModelNumber(), partBo.getSectionNumber(),
            partBo.getComponentNumber(), partBo.getPartNumber());

        List<IsfdModelManagementPart> existingVersionList = baseMapper.selectList(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(IsfdModelManagementPart::getModelNumber, partBo.getModelNumber())
            .eq(IsfdModelManagementPart::getBatchNumber, partBo.getBatchNumber())
            .eq(IsfdModelManagementPart::getSectionNumber, partBo.getSectionNumber())
            .eq(IsfdModelManagementPart::getComponentNumber, partBo.getComponentNumber())
            .eq(IsfdModelManagementPart::getPartNumber, partBo.getPartNumber()));
        if (CollectionUtils.isEmpty(existingVersionList)) {
            log.error("未查询到相关零件！,零件索引: {}", partIndex);
            throw new BaseException("未查询到相关零件！,零件索引: " + partIndex);
        }
        // 将 version 和 remarks 字段转换为 Map<String, String>
        return existingVersionList.stream()
            .collect(Collectors.toMap(
                IsfdModelManagementPart::getVersionNumber, // 作为 key
                part -> part.getRemarks() == null ? "" : part.getRemarks(), // 处理 value 为 null 的情况
                (existing, replacement) -> {
                    log.error("查询零件历史版本时，发现重复版本号！,零件索引：{}, 版本号：{}.", partIndex, existing);
                    throw new BaseException(
                        String.format("查询零件历史版本时，发现重复版本号！,零件索引：%s, 版本号：%s.", partIndex, existing)
                    );
                }));
    }

    /**
     * 查询零件原始信息
     */
    private void buildOriginalDetailToPart(IsfdModelManagementPartVo partVo, String originalPartNumber) {
        List<IsfdDetailOriginalV2BomVo> originalV2BomVoList = isfdModelManagementOriginalPartConfig.queryOriginalBomByStrength(partVo.getModelNumber(), partVo.getBatchNumber()
            , partVo.getSectionNumber(), originalPartNumber);
        if (!CollectionUtils.isEmpty(originalV2BomVoList)) {
            IsfdDetailOriginalV2BomVo isfdDetailOriginalV2BomVo = originalV2BomVoList.get(0);
            partVo.setName(isfdDetailOriginalV2BomVo.getName());
            partVo.setAmount(Long.valueOf(isfdDetailOriginalV2BomVo.getCnt()));
            partVo.setUnitWeight(StringUtils.isNotBlank(isfdDetailOriginalV2BomVo.getWeight()) ?
                Double.parseDouble(isfdDetailOriginalV2BomVo.getWeight()) : null);
            partVo.setMaterial(isfdDetailOriginalV2BomVo.getMaterialCode());
            partVo.setExitCheck(OriginalPartExitCchekEnum.EXIT.getValue());
        } else {
            partVo.setExitCheck(OriginalPartExitCchekEnum.NOT_EXIT.getValue());
        }
    }

    /**
     * 查询原始文件
     */
    private List<IsfdDetailOriginalV2BomVo> findOriginalPart(String modelNumber, String batchNumber, String sectionNumber, String originalPartNumber) {
        List<IsfdDetailOriginalV2BomVo> isfdDetailOriginalV2BomVoList = isfdModelManagementOriginalPartConfig.queryOriginalBomByStrength(modelNumber, batchNumber
            , sectionNumber, originalPartNumber);
        if (CollectionUtils.isEmpty(isfdDetailOriginalV2BomVoList)) {
            log.error("没有找到原始清单数据,modelNumber : {}, batchNumber : {}, sectionNumber: {} , originalPartNumber: {}",
                modelNumber, batchNumber, sectionNumber, originalPartNumber);
            return null;
        }
        return isfdDetailOriginalV2BomVoList;
    }

    private List<String> checkAndAddSection(String modelNumber, String batchNumber, List<String> allPath, String tempPath) {
        // 当前传入机型是否存在
        IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null);
        if (modelVo == null) {
            throw new BaseException("所选机型不存在，请确认后重试。");
        }
        // 当前传入批次是否存在
        IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null);
        if (batchVo == null) {
            throw new BaseException("所选批次不存在，请确认后重试。");
        }
        // 当前传入部段是否存在
        IsfdModelManagementStructureDefinitionTreeBo queryBo = new IsfdModelManagementStructureDefinitionTreeBo();
        queryBo.setParentId(batchVo.getId());
        List<IsfdModelManagementStructureDefinitionTreeVo> sectionVoList = iIsfdModelManagementStructureDefinitionTreeService.queryList(queryBo);
        if (CollectionUtils.isEmpty(sectionVoList)) {
            throw new BaseException("所选机型-批次 不存在部段，请确认后重试。");
        }
        List<String> sectionStrList = sectionVoList.stream().map(IsfdModelManagementStructureDefinitionTreeVo::getMark).toList();

        Set<String> newSectionStrSet = new HashSet<>();
        // 机型和部段对压缩包的数据进行过滤
        List<String> newAllPath = new ArrayList<>();
        Path prefixPath = Paths.get(tempPath);
        for (String a : allPath) {
            Path path = Paths.get(a);
            if (path.getNameCount() == prefixPath.getNameCount() + 3) {
                Path modelNumberPath = getSpecificLevel(path, prefixPath.getNameCount() + 2);
                String targetModelNumber = modelNumberPath.toString();
                if (!targetModelNumber.contains(modelVo.getMark())) {
                    throw new BaseException("上传文件结构不对，请确认文件压缩包名称 和 机型索引文件名 是否包含选择的机型编号。");
                }
                newAllPath.add(a);
                continue;
            }

            Path sectionNumberPath = getSpecificLevel(path, prefixPath.getNameCount() + 3);
            String targetSectionNumber = sectionNumberPath.toString();
            Optional<String> optional = sectionStrList.stream().filter(targetSectionNumber::contains).findFirst();
            if (optional.isEmpty()) {
                newSectionStrSet.add(targetSectionNumber);
            }
            newAllPath.add(a);
        }
        // 把在构型定义中没有的部段加上
        if (CollectionUtils.isNotEmpty(newSectionStrSet)) {
            for (String sectionNumber : newSectionStrSet) {
                IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
                if (sectionVo != null) {
                    continue;
                }
                IsfdModelManagementStructureDefinitionTreeBo bo = new IsfdModelManagementStructureDefinitionTreeBo();
                bo.setMark(sectionNumber);
                bo.setName(sectionNumber);
                String sectionJsonStr = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
                    CommonConstant.STRUCTURE_DEFINITION_SECTION);
                if (StringUtils.isNotBlank(sectionJsonStr)) {
                    JSONObject dict = new JSONObject(sectionJsonStr);
                    Optional<String> first = dict.keySet().stream().filter(sectionNumber::contains).findFirst();
                    first.ifPresent(s -> bo.setName(dict.getStr(s)));
                }
                bo.setLevel(IsfdStructureDefinitionTreeLevelEnum.SECTION.getValue());
                bo.setParentId(batchVo.getId());
                iIsfdModelManagementStructureDefinitionTreeService.insertByBo(bo);
            }
        }
        return newAllPath;
    }

    private List<String> componentCheckAndFilterPath(String modelNumber, String batchNumber, String sectionNumber, List<String> allPath, String tempPath) {
        // 当前传入机型是否存在
        IsfdModelManagementStructureDefinitionTreeVo modelVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null);
        if (modelVo == null) {
            throw new BaseException("所选机型不存在，请确认后重试。");
        }
        // 当前传入批次是否存在
        IsfdModelManagementStructureDefinitionTreeVo batchVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null);
        if (batchVo == null) {
            throw new BaseException("所选批次不存在，请确认后重试。");
        }
        // 当前传入部段是否存在
        List<String> sectionStrList = new ArrayList<>();
        IsfdModelManagementStructureDefinitionTreeBo queryBo = new IsfdModelManagementStructureDefinitionTreeBo();
        List<IsfdModelManagementStructureDefinitionTreeVo> sectionVoList = null;
        if (StringUtils.isBlank(sectionNumber)) {
            queryBo.setParentId(batchVo.getId());
            sectionVoList = iIsfdModelManagementStructureDefinitionTreeService.queryList(queryBo);
        } else {
            IsfdModelManagementStructureDefinitionTreeVo sectionVo = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber);
            sectionVoList = new ArrayList<>();
            sectionVoList.add(sectionVo);
        }

        if (CollectionUtils.isEmpty(sectionVoList)) {
            throw new BaseException("所选机型-批次 不存在部段，请确认后重试。");
        }
        sectionStrList = sectionVoList.stream().map(IsfdModelManagementStructureDefinitionTreeVo::getMark).toList();

        // 机型和部段对压缩包的数据进行过滤
        List<String> newAllPath = new ArrayList<>();
        Path prefixPath = Paths.get(tempPath);
        for (String a : allPath) {
            Path path = Paths.get(a);
            if (path.getNameCount() == prefixPath.getNameCount() + 3) {
                Path modelNumberPath = getSpecificLevel(path, prefixPath.getNameCount() + 2);
                String targetModelNumber = modelNumberPath.toString();
                if (!targetModelNumber.contains(modelVo.getMark())) {
                    throw new BaseException("上传文件结构不对，请确认文件压缩包名称 和 机型索引文件名 是否包含选择的机型编号。");
                }
                newAllPath.add(a);
                continue;
            }

            Path sectionNumberPath = getSpecificLevel(path, prefixPath.getNameCount() + 3);
            String targetSectionNumber = sectionNumberPath.toString();
            Optional<String> optional = sectionStrList.stream().filter(targetSectionNumber::contains).findFirst();
            if (optional.isPresent()) {
                newAllPath.add(a);
            }
        }
        return newAllPath;
    }


    private Path getSpecificLevel(Path path, int levelIndex) {
        Path result = null;

        // 迭代器遍历路径的每个部分
        Iterator<Path> iterator = path.iterator();
        int currentLevel = 0; // 层级计数器，从0开始

        while (iterator.hasNext()) {
            Path part = iterator.next();
            currentLevel++; // 每迭代一次，层级+1
            if (currentLevel == levelIndex) {
                result = part;
            }
        }
        return result;
    }

    /**
     * 整机导入-规则检查 第三步
     */
    private List<IsfdModelManagementPartVo> analyzeFileIndexAndReturnVoListPartitions(List<String> allPath, String fileName, String tempPath,
                                                                                      String modelNumber, String batchNumber, String indexFileName) throws IOException {
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();

        // 第一层：机型
        String modelIndexPathWithTempStr = findModelIndexPath(allPath, fileName, tempPath, indexFileName);
        String modelIndexPath = null;
        String sortie = null;
        if (StringUtils.isNotEmpty(modelIndexPathWithTempStr)) {
            Path modelIndexPathWithTemp = Paths.get(modelIndexPathWithTempStr);
            String partName = modelIndexPathWithTemp.getFileName().toString();
            Path tempPathObject = Paths.get(tempPath);
            modelIndexPath = modelIndexPathWithTemp.toString().replace(tempPathObject.toString(), "");
            modelIndexPath = modelIndexPath.replace("\\", "/");
            modelIndexPath = modelIndexPath.startsWith("/") ? modelIndexPath.substring(1) : modelIndexPath;
            sortie = RegexMatcher.getSortie(modelIndexPath, modelNumber);
            String[] partNumberAndVersion = RegexMatcher.getPartNumber(partName);
            //根据零件名称查询文件是否存在
            IsfdModelManagementPartVo partVo = this.getUniquePartVo(modelNumber, batchNumber, null, null, partName);
            if (partVo == null) {
                partVo = new IsfdModelManagementPartVo();
                partVo.setModelNumber(modelNumber);
                partVo.setSortie(sortie);
                partVo.setBatchNumber(batchNumber);
                partVo.setPartName(partName);
                partVo.setPartNumber(partNumberAndVersion[0]);
                partVo.setFileSize(Files.size(modelIndexPathWithTemp));
                partVo.setModelIndex(RegexMatcher.reBuildIndexPath(modelIndexPath, modelNumber));
                partVo.setIndexPath(RegexMatcher.reBuildIndexPath(modelIndexPath, modelNumber));
                partVo.setFileName(partName);
                partVo.setFileLevel(PartFileLevelEnum.MODEL.getValue());
                partVo.setFileType(PartFileTypeEnum.INDEX.getValue());
                partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
            } else {
                partVo.setSortie(sortie);
                partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
            }

            partVoList.add(partVo);
        } else {
            throw new BaseException("机型索引文件不存在，请确认后重试！");
        }


        //第二层：部段
        List<String> sectionIndexPathList = new ArrayList<>();
        List<String> modelAndSectionResultList = extractLinesStarting(modelIndexPath, tempPath);
        if (CollectionUtils.isNotEmpty(modelAndSectionResultList)) {
            for (String result : modelAndSectionResultList) {
                sectionIndexPathList.add(modelIndexPath + "," + batchNumber + "/" + result);
            }
        }
        if (CollectionUtils.isEmpty(sectionIndexPathList)) {
            throw new BaseException("部段索引文件不存在，请确认后重试！");
        }
        List<String> componentIndexPathList = new ArrayList<>();
        for (String sectionIndexMix : sectionIndexPathList) {
            //获取索引关联关系
            String[] split = sectionIndexMix.split(",");
            String modelIndex = split[0];
            String sectionIndex = split[1];
            //获取文件内容
            List<String> resultList = extractLinesStarting(sectionIndex, tempPath);
            if (resultList == null) {
                log.info("索引中指定的文件不存在，全链路： {}", sectionIndexMix);
                continue;
            }
            //获取文件名
            Path sectionIndexPath = Paths.get(tempPath + sectionIndex);
            String partName = sectionIndexPath.getFileName().toString();
            String[] partNumberAndVersion = RegexMatcher.getPartNumber(partName);

            //获取机型、部段
            String[] sectionIndexPaths = sectionIndex.split("/");
            String sectionNumber = null;
            String fileLevel = null;
            if (sectionIndexPaths.length > 2) {
                sectionNumber = sectionIndexPaths[2];
                fileLevel = PartFileLevelEnum.SECTION.getValue();
            } else {
                fileLevel = PartFileLevelEnum.MODEL.getValue();
            }

            //根据零件名称查询文件是否存在
            IsfdModelManagementPartVo partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, null, partName);
            if (partVo == null) {
                partVo = new IsfdModelManagementPartVo();
                partVo.setSectionNumber(sectionNumber);
                partVo.setFileLevel(fileLevel);
                partVo.setModelNumber(modelNumber);
                partVo.setSortie(sortie);
                partVo.setBatchNumber(batchNumber);
                partVo.setPartName(partName);
                partVo.setPartNumber(partNumberAndVersion[0]);
                partVo.setFileSize(Files.size(sectionIndexPath));
                partVo.setModelIndex(RegexMatcher.reBuildIndexPath(modelIndex, modelNumber));
                partVo.setSectionIndex(RegexMatcher.reBuildIndexPath(sectionIndex, modelNumber));
                partVo.setIndexPath(RegexMatcher.reBuildIndexPath(sectionIndex, modelNumber));
                partVo.setFileName(partName);
                partVo.setVersionNumber(partNumberAndVersion[1]);
                //设置 文件类型
                partVo.setFileType(RegexMatcher.matchesPartFileType(partNumberAndVersion[0], resultList).getValue());
                partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
            } else {
                partVo.setSortie(sortie);
                partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
            }
            if (CollectionUtils.isNotEmpty(resultList)) {
                for (String result : resultList) {
                    componentIndexPathList.add(sectionIndexMix + "," + batchNumber + "/" + result);
                }
            }
            partVoList.add(partVo);
        }

        if (CollectionUtils.isEmpty(componentIndexPathList)) {
            throw new BaseException("组件索引文件不存在，请确认后重试！");
        }

        //第三层：组件
        List<String> partIndexPathList = new ArrayList<>();
        for (String componentIndexMix : componentIndexPathList) {
            //获取索引关联关系
            String[] split = componentIndexMix.split(",");
            String modelIndex = split[0];
            String sectionIndex = split[1];
            String componentIndex = split[2];
            //获取文件内容
            List<String> resultList = extractLinesStarting(componentIndex, tempPath);
            if (resultList == null) {
                log.info("索引中指定的文件不存在，全链路： {}", componentIndexMix);
                continue;
            }
            //获取文件名
            Path componentIndexPath = Paths.get(tempPath + componentIndex);
            String partName = componentIndexPath.getFileName().toString();
            String[] partNumberAndVersion = RegexMatcher.getPartNumber(partName);

            //获取机型、部段、组件编号
            String[] componentIndexPaths = componentIndex.split("/");
            String sectionNumber = componentIndexPaths[1];
            String componentNumber = componentIndexPaths[2];
            //根据零件名称查询文件是否存在
            IsfdModelManagementPartVo partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, componentNumber, partName);
            if (partVo == null) {
                partVo = new IsfdModelManagementPartVo();
                partVo.setModelNumber(modelNumber);
                partVo.setSortie(sortie);
                partVo.setSectionNumber(sectionNumber);
                partVo.setComponentNumber(componentNumber);
                partVo.setPartName(partName);
                partVo.setPartNumber(partNumberAndVersion[0]);
                partVo.setFileSize(Files.size(componentIndexPath));
                partVo.setModelIndex(RegexMatcher.reBuildIndexPath(modelIndex, modelNumber));
                partVo.setSectionIndex(RegexMatcher.reBuildIndexPath(sectionIndex, modelNumber));
                partVo.setComponentIndex(RegexMatcher.reBuildIndexPath(componentIndex, modelNumber));
                partVo.setIndexPath(RegexMatcher.reBuildIndexPath(componentIndex, modelNumber));
                partVo.setFileName(partName);
                partVo.setFileLevel(PartFileLevelEnum.COMPONENT.getValue());
                partVo.setVersionNumber(partNumberAndVersion[1]);
                //设置 文件类型
                partVo.setFileType(RegexMatcher.matchesPartFileType(partNumberAndVersion[0], resultList).getValue());
                partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
            } else {
                partVo.setSortie(sortie);
                partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
            }

            if (CollectionUtils.isNotEmpty(resultList)) {
                for (String result : resultList) {
                    partIndexPathList.add(componentIndexMix + "," + batchNumber + "/" + result);
                }
            }
            partVoList.add(partVo);
        }

        if (CollectionUtils.isEmpty(partIndexPathList)) {
            throw new BaseException("零件文件不存在，请确认后重试！");
        }

        // 数据分批
        List<List<String>> partitions = new ArrayList<>();
        int batchSize = partIndexPathList.size() / BATCH_NUMBER_SIZE;
        if (batchSize == 0) {
            partitions.add(partIndexPathList);
        } else {
            for (int i = 0; i < partIndexPathList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, partIndexPathList.size());
                partitions.add(partIndexPathList.subList(i, end));
            }
        }

        ExecutorService executor = Executors.newFixedThreadPool(BATCH_NUMBER_SIZE);
        List<Future<List<IsfdModelManagementPartIndexPathListDealVo>>> futures = new ArrayList<>();
        // 循环分批启用线程处理数据
        for (List<String> partition : partitions) {
            String finalSortie = sortie;
            Future<List<IsfdModelManagementPartIndexPathListDealVo>> future = executor.submit(() -> {
                try {
                    //第四层 零件
                    return partIndexPathListDeal(tempPath, modelNumber, finalSortie, batchNumber, partition);
                } catch (Exception e) {
                    log.error("分批次规则检查失败", e);
                    throw new BaseException(e.getMessage());
                }
            });
            futures.add(future);
        }

        try {
            executor.shutdown();
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (Exception e) {
            log.error("分批次规则检查等待失败", e);
            throw new BaseException("分批次规则检查等待失败");
        }

        // 合并数据
        List<IsfdModelManagementPartIndexPathListDealVo> result = new ArrayList<>();
        for (Future<List<IsfdModelManagementPartIndexPathListDealVo>> future : futures) {
            try {
                List<IsfdModelManagementPartIndexPathListDealVo> innerResult = future.get();
                Map<String, IsfdModelManagementPartIndexPathListDealVo> tempMap = innerResult.stream()
                    .collect(Collectors.toMap(
                        IsfdModelManagementPartIndexPathListDealVo::getOriginalPartNumber,
                        vo -> vo,
                        (existing, replacement) -> {
                            existing.getPartVoList().addAll(replacement.getPartVoList());
                            return existing;
                        }
                    ));
                result.addAll(tempMap.values());
            } catch (Exception e) {
                log.error("分批次规则检查合并失败", e);
                throw new BaseException("分批次规则检查合并失败");
            }
        }

        // 封装统计导入数量是否和原始清单匹配
        for (IsfdModelManagementPartIndexPathListDealVo dealVo : result) {
            List<IsfdModelManagementPartVo> innerPartVo = dealVo.getPartVoList();
            int importCount = innerPartVo.size();
            Long originalImportCount = dealVo.getOriginalImportCount();
            if (importCount != originalImportCount.intValue()) {
                for (IsfdModelManagementPartVo p : innerPartVo) {
                    if (OriginalPartExitCchekEnum.EXIT.getValue().equals(p.getExitCheck())) {
                        p.setCountCheck(OriginalPartCountCchekEnum.NOT_MATCH.getValue());
                        p.setImportCount((long) importCount);
                        p.setOriginalImportCount(originalImportCount);
                    }
                }
            }
            partVoList.addAll(innerPartVo);
        }
        return partVoList;
    }

    /**
     * 整机导入-规则检查数据处理
     */
    private List<IsfdModelManagementPartIndexPathListDealVo> partIndexPathListDeal(String tempPath,
                                                                                   String modelNumber,
                                                                                   String sortie,
                                                                                   String batchNumber,
                                                                                   List<String> partIndexPathList) {
        List<IsfdModelManagementPartIndexPathListDealVo> dealVoList = new ArrayList<>();
        try {
            for (String partIndexMix : partIndexPathList) {
                //获取索引关联关系
                String[] split = partIndexMix.split(",");
                String modelIndex = split[0];
                String sectionIndex = split[1];
                String componentIndex = split[2];
                String partIndex = split[3];
                //获取文件名
                Path partIndexPath = Paths.get(tempPath + partIndex);
                String partName = partIndexPath.getFileName().toString();
                String[] partNumberAndVersion = RegexMatcher.getPartNumber(partName);
                String partNumber = partNumberAndVersion[0];
                String versionNumber = partNumberAndVersion[1];

                List<String> resultList = extractLinesStarting(partIndex, tempPath);
                if (resultList == null) {
                    log.info("索引中指定的文件不存在，全链路： {}", partIndexMix);
                    continue;
                }
                //获取机型、部段、组件编号
                String[] partIndexPaths = partIndex.split("/");
                String sectionNumber = partIndexPaths[2];
                String componentNumber = partIndexPaths[3];
                //根据零件名称查询文件是否存在
                IsfdModelManagementPartVo partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, componentNumber, partName);
                if (partVo == null) {
                    partVo = new IsfdModelManagementPartVo();
                    partVo.setModelNumber(modelNumber);
                    partVo.setSortie(sortie);
                    partVo.setBatchNumber(batchNumber);
                    partVo.setSectionNumber(sectionNumber);
                    partVo.setComponentNumber(componentNumber);
                    partVo.setPartName(partName);
                    partVo.setPartNumber(partNumber);
                    partVo.setVersionNumber(versionNumber);
                    partVo.setFileSize(Files.size(partIndexPath));
                    partVo.setModelIndex(RegexMatcher.reBuildIndexPath(modelIndex, modelNumber));
                    partVo.setSectionIndex(RegexMatcher.reBuildIndexPath(sectionIndex, modelNumber));
                    partVo.setComponentIndex(RegexMatcher.reBuildIndexPath(componentIndex, modelNumber));
                    partVo.setIndexPath(RegexMatcher.reBuildIndexPath(partIndex, modelNumber));
                    partVo.setFileName(partName);
                    partVo.setFileLevel(PartFileLevelEnum.COMPONENT.getValue());
                    partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                    partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
                    // 设置 文件类型
                    partVo.setFileType(RegexMatcher.matchesPartFileType(partNumber, resultList).getValue());
                } else {
                    // 文件大小展示当前 导入文件大小
                    partVo.setFileSize(Files.size(partIndexPath));
                    partVo.setSortie(sortie);
                    partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                    partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
                }

                // 查询 原始装机零件
                initOriginalPartInfo(modelNumber, batchNumber, sectionNumber, partNumber, versionNumber, partVo, dealVoList);
            }
        } catch (Exception e) {
            log.error("多线程处理失败", e);
            throw new BaseException("多线程处理失败");
        }

        return dealVoList;
    }

    /**
     * 整机导入-预导入数据处理
     */
    private List<IsfdModelManagementPartVo> preImportDealData(List<IsfdModelManagementPreImportPartBo> preImportPartBoList,
                                                              String modelNumber,
                                                              String batchNumber) {
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        for (IsfdModelManagementPreImportPartBo bo : preImportPartBoList) {
            String partName = bo.getPartName();
            String sectionNumber = bo.getSectionNumber();
            String componentNumber = bo.getComponentNumber();
            IsfdModelManagementPartVo partVo = null;
            if (PartFileLevelEnum.MODEL.getValue().equals(bo.getFileLevel())) {
                partVo = getUniquePartVo(modelNumber, null, null, null, partName);
            } else if (PartFileLevelEnum.SECTION.getValue().equals(bo.getFileLevel())) {
                partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, null, partName);
            } else if (PartFileLevelEnum.COMPONENT.getValue().equals(bo.getFileLevel())) {
                partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, componentNumber, partName);
            } else {
                throw new BaseException("文件级别 不存在，请确认后重试");
            }

            if (partVo == null) {
                partVo = new IsfdModelManagementPartVo();
                BeanUtils.copyProperties(bo, partVo);
                partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
            } else {
                partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
            }

            partVoList.add(partVo);
        }
        return partVoList;
    }

    /**
     * 整机导入-确认导入数据处理
     */
    private IsfdModelManagementConfirmImportPartVo confirmImportDealData(List<IsfdModelManagementPartBo> resultPartBoList,
                                                                         Map<String, IsfdModelManagementStructureDefinitionTreeVo> sectionMap,
                                                                         String modelNumber,
                                                                         String modelName,
                                                                         String batchNumber,
                                                                         String batchName,
                                                                         String tempPath,
                                                                         String targetPath,
                                                                         Long userId,
                                                                         Long deptId) {
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        long importNumber = 0;
        long updatedImportNumber = 0;
        long notImportNumber = 0;
        long failImportNumber = 0;
        IsfdModelManagementConfirmImportPartVo resultVo = new IsfdModelManagementConfirmImportPartVo();
        for (IsfdModelManagementPartBo bo : resultPartBoList) {
            // 1. 筛选出不需要入库的 导入操作标记
            // WAIT_FLAG(1, "待标记"),ABLE_IMPORT(2, "可导入"),NOT_IMPORT(3, "不导入"),UPDATED(4, "已修改") 中
            // WAIT_FLAG 和 NOT_IMPORT 直接修改状态返回给前端
            Integer importOperationTags = bo.getImportOperationTags();
            if (ImportOperationTagsEnum.WAIT_FLAG.getValue().equals(importOperationTags) ||
                ImportOperationTagsEnum.NOT_IMPORT.getValue().equals(importOperationTags)) {
                IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
                notImportNumber++;
                vo.setImportResultStatus(ImportResultStatusEnum.NOT_IMPORT.getValue());
                partVoList.add(vo);
                continue;
            }

            // 2.判断修改的零件号和版本号是否已存在
            String partNumber = bo.getPartNumber();
            String versionNumber = bo.getVersionNumber();
            String partName = partNumber + "_" + versionNumber + ".bdf";
            IsfdModelManagementPartVo targetVo = getUniquePartVo(bo.getModelNumber(), bo.getBatchNumber(), bo.getSectionNumber(), bo.getComponentNumber(), partName);
            if (targetVo != null && !targetVo.getId().equals(bo.getId())) {
                log.error("导入失败，零件号和版本号与数据库数据重名！");
                IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
                failImportNumber++;
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_FAIL.getValue());
                partVoList.add(vo);
                continue;
            }

            // 3. 查询出机型名称、批次名称和部段名称
            bo.setModelName(modelName);
            // 部段不要每次都查db
            String sectionName = null;
            if (StringUtils.isNotBlank(bo.getSectionNumber())) {
                if (sectionMap.get(bo.getSectionNumber()) == null) {
                    IsfdModelManagementStructureDefinitionTreeVo isfdModelManagementStructureDefinitionTreeVo = iIsfdModelManagementStructureDefinitionTreeService
                        .queryOneByQueryIndex(modelNumber, batchNumber, bo.getSectionNumber());
                    sectionMap.put(bo.getSectionNumber(), isfdModelManagementStructureDefinitionTreeVo);
                    sectionName = isfdModelManagementStructureDefinitionTreeVo.getName();
                } else {
                    sectionName = sectionMap.get(bo.getSectionNumber()).getName();
                }
            }
            bo.setSectionName(sectionName);

            IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
            try {
                // 4. 写入磁盘文件，把临时目录下的文件 移动 到最终目录下
                IsfdModelManagementPart po = MapstructUtils.convert(bo, IsfdModelManagementPart.class);
                po.setPartName(partName);
                String indexPath = bo.getIndexPath();
                po.setIndexPath(StringUtils.substringBeforeLast(indexPath, "/") + "/" + po.getPartName());
                String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, batchNumber, indexPath, po.getSortie());
                String newIndexPath = RegexMatcher.getDataPath(targetPath, batchNumber, po.getIndexPath());
                FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);
                if (StringUtils.isNotBlank(bo.getComponentIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.COMPONENT.getValue())
                    && bo.getComponentIndex().equals(bo.getIndexPath())) {
                    po.setComponentIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getSectionIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.SECTION.getValue())
                    && bo.getSectionIndex().equals(bo.getIndexPath())) {
                    po.setSectionIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getModelIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.MODEL.getValue())
                    && bo.getModelIndex().equals(bo.getIndexPath())) {
                    po.setModelIndex(po.getIndexPath());
                }
                po.setPartNumber(partNumber);
                po.setVersionNumber(versionNumber);
                po.setFileName(partName);
                po.setCreateDept(deptId);
                // 5. 存入DB
                if (bo.getId() != null) {
                    po.setUpdateBy(userId);
                    baseMapper.updateById(po);
                } else {
                    po.setCreateBy(userId);
                    po.setUpdateBy(userId);
                    baseMapper.insert(po);
                }

                //6. 返回封装vo
                vo = MapstructUtils.convert(po, IsfdModelManagementPartVo.class);
                if (ImportOperationTagsEnum.ABLE_IMPORT.getValue().equals(importOperationTags)) {
                    importNumber++;
                    vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_SUCCESS.getValue());
                } else if (ImportOperationTagsEnum.UPDATED.getValue().equals(importOperationTags)) {
                    vo.setImportResultStatus(ImportResultStatusEnum.UPDATED_IMPORT.getValue());
                    updatedImportNumber++;
                } else {
                    log.error("当前数据未定义操作类型，partName是:{} , indexPath是:{}", bo.getPartName(), bo.getIndexPath());
                }
                partVoList.add(vo);
            } catch (Exception e) {
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_FAIL.getValue());
                failImportNumber++;
                partVoList.add(vo);
                log.error("导入失败", e);
            }
        }
        resultVo.setPartVoList(partVoList);
        resultVo.setImportNumber(importNumber);
        resultVo.setFailImportNumber(failImportNumber);
        resultVo.setNotImportNumber(notImportNumber);
        resultVo.setUpdatedImportNumber(updatedImportNumber);
        return resultVo;
    }

    /**
     * 覆盖-整机导入数据处理
     */
    private IsfdModelManagementConfirmImportPartVo coverConfirmImportDealData(List<IsfdModelManagementPartBo> resultPartBoList,
                                                                              Map<String, IsfdModelManagementStructureDefinitionTreeVo> sectionMap,
                                                                              String modelNumber,
                                                                              String modelName,
                                                                              String batchNumber,
                                                                              String batchName,
                                                                              String tempPath,
                                                                              String targetPath,
                                                                              Long userId,
                                                                              Long deptId) {
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        long importNumber = 0;
        long updatedImportNumber = 0;
        long notImportNumber = 0;
        long failImportNumber = 0;
        IsfdModelManagementConfirmImportPartVo resultVo = new IsfdModelManagementConfirmImportPartVo();
        for (IsfdModelManagementPartBo bo : resultPartBoList) {
            Integer importOperationTags = bo.getImportOperationTags();
            String partNumber = bo.getPartNumber();
            String versionNumber = bo.getVersionNumber();
            String partName = partNumber + "_" + versionNumber + ".bdf";

            // 1.查询出机型名称、批次名称和部段名称
            bo.setModelName(modelName);
            // 部段不要每次都查db
            String sectionName = null;
            if (StringUtils.isNotBlank(bo.getSectionNumber())) {
                if (sectionMap.get(bo.getSectionNumber()) == null) {
                    IsfdModelManagementStructureDefinitionTreeVo isfdModelManagementStructureDefinitionTreeVo = iIsfdModelManagementStructureDefinitionTreeService
                        .queryOneByQueryIndex(modelNumber, batchNumber, bo.getSectionNumber());
                    sectionMap.put(bo.getSectionNumber(), isfdModelManagementStructureDefinitionTreeVo);
                    sectionName = isfdModelManagementStructureDefinitionTreeVo.getName();
                } else {
                    sectionName = sectionMap.get(bo.getSectionNumber()).getName();
                }
            }
            bo.setSectionName(sectionName);

            IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
            try {
                // 2. 写入磁盘文件，把临时目录下的文件 移动 到最终目录下
                IsfdModelManagementPart po = MapstructUtils.convert(bo, IsfdModelManagementPart.class);
                po.setPartName(partName);
                String indexPath = bo.getIndexPath();
                po.setIndexPath(StringUtils.substringBeforeLast(indexPath, "/") + "/" + po.getPartName());
                String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, batchNumber, indexPath, po.getSortie());
                String newIndexPath = RegexMatcher.getDataPath(targetPath, batchNumber, po.getIndexPath());
                FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);
                if (StringUtils.isNotBlank(bo.getComponentIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.COMPONENT.getValue())
                    && bo.getComponentIndex().equals(bo.getIndexPath())) {
                    po.setComponentIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getSectionIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.SECTION.getValue())
                    && bo.getSectionIndex().equals(bo.getIndexPath())) {
                    po.setSectionIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getModelIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.MODEL.getValue())
                    && bo.getModelIndex().equals(bo.getIndexPath())) {
                    po.setModelIndex(po.getIndexPath());
                }
                po.setPartNumber(partNumber);
                po.setVersionNumber(versionNumber);
                po.setFileName(partName);
                po.setCreateDept(deptId);
                po.setCreateBy(userId);
                po.setUpdateBy(userId);
                //3.存入DB
                int insert = baseMapper.insert(po);

                //4. 返回封装vo
                vo = MapstructUtils.convert(po, IsfdModelManagementPartVo.class);
                importNumber++;
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_SUCCESS.getValue());
                partVoList.add(vo);
            } catch (Exception e) {
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_FAIL.getValue());
                failImportNumber++;
                partVoList.add(vo);
                log.error("导入失败", e);
            }
        }
        resultVo.setPartVoList(partVoList);
        resultVo.setImportNumber(importNumber);
        resultVo.setFailImportNumber(failImportNumber);
        resultVo.setNotImportNumber(notImportNumber);
        resultVo.setUpdatedImportNumber(updatedImportNumber);
        return resultVo;
    }

    /**
     * 寻找索引文件
     * 根据是否输入索引文件名来判断
     * 如果没有输入，索引文件名需要和压缩包文件名一致
     */
    private String findModelIndexPath(List<String> allPath, String fileName, String tempPath, String indexFileName) {
        Path prefixPath = Paths.get(tempPath);
        List<String> modelIndexList = allPath.stream().filter(a -> {
            Path path = Paths.get(a);
            return (path.getNameCount() == prefixPath.getNameCount() + 3) && a.endsWith(".bdf");
        }).toList();
        if (CollectionUtils.isEmpty(modelIndexList)) {
            log.error("解压包中不包含机型索引文件，请确认后重试！");
            throw new BaseException("解压包中不包含机型索引文件，请确认后重试！");
        }

        // 如果输入索引文件名
        if (StringUtils.isNotBlank(indexFileName)) {
            for (String a : modelIndexList) {
                Path path = Paths.get(a);
                String targetIndexFileName = path.getFileName().toString().replace(".bdf", "");
                if (!targetIndexFileName.equals(indexFileName)) {
                    continue;
                }
                List<String> resultList = extractLinesStarting(a, tempPath);
                if (CollectionUtils.isNotEmpty(resultList)) {
                    return a;
                }
            }
        }

        // 如果不输入索引文件名
        for (String a : modelIndexList) {
            Path modelIndexPathWithTemp = Paths.get(a);
            String partName = modelIndexPathWithTemp.getFileName().toString();
            if (partName.startsWith(fileName)) {
                List<String> resultList = extractLinesStarting(a, tempPath);
                if (CollectionUtils.isNotEmpty(resultList)) {
                    return a;
                }
            }
        }
        return null;
    }

    /**
     * 查询唯一零件
     */
    @Override
    public IsfdModelManagementPartVo getUniquePartVo(String modelNumber, String batchNumber, String sectionNumber, String componentNumber, String partName) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<IsfdModelManagementPart>()
            .eq(StringUtils.isNotBlank(modelNumber), IsfdModelManagementPart::getModelNumber, modelNumber)
            .eq(StringUtils.isNotBlank(batchNumber), IsfdModelManagementPart::getBatchNumber, batchNumber)
            .eq(StringUtils.isNotBlank(sectionNumber), IsfdModelManagementPart::getSectionNumber, sectionNumber)
            .eq(StringUtils.isNotBlank(componentNumber), IsfdModelManagementPart::getComponentNumber, componentNumber)
            .eq(IsfdModelManagementPart::getPartName, partName));
    }

    public static List<String> extractLinesStarting(String filePath, String prePathStr) {
        List<String> extractedStrings = new ArrayList<>();
        Path path = Paths.get(filePath);
        Path prePath = Paths.get(prePathStr);
        if (!path.startsWith(prePath)) {
            path = Paths.get(prePathStr + filePath);
        }

        if (!Files.exists(path)) {
            log.error("path为:{} 系统找不到指定的文件！", path);
            return null;
        }
        try (BufferedReader br = new BufferedReader(new FileReader(path.toString()))) {
            String line;
            while ((line = br.readLine()) != null) {
                if (line.startsWith(CommonConstant.INCLUDE)) {
                    //1. 每一行先截取掉 INCLUDE
                    String extractedData = line.substring(CommonConstant.INCLUDE.length());
                    //2. 继续截取掉前后的' 单引号
                    if (extractedData.startsWith("'") && extractedData.endsWith("'")) {
                        extractedData = extractedData.substring(1, extractedData.length() - 1).trim();
                    }
                    //补一刀
                    if (extractedData.contains("'")) {
                        extractedData = extractedData.replaceAll("'", "");
                    }
                    //再补一刀
                    if (StringUtils.isNotBlank(extractedData)) {
                        extractedData = extractedData.trim();
                    }
                    if (extractedData.endsWith(".bdf") || extractedData.endsWith(".BDF")) {
                        extractedStrings.add(extractedData);
                    }
                }
            }
        } catch (IOException e) {
            log.error("extract lines starting is fail.", e);
        }

        return extractedStrings;
    }

    @Transactional
    public String deletePartById(Long id) {
        IsfdModelManagementPart part = baseMapper.selectById(id);
        if (part == null) {
            log.error("未查询到零件，零件id: {}", id);
            throw new BaseException("未查询到零件，零件id: " + id);
        }
        String bdfPath = part.getIndexPath();
        if (bdfPath == null) {
            log.error("未查询到文件保存路径，零件id: {}", id);
            throw new BaseException("未查询到文件保存路径，零件id: " + id);
        }

        String bdfPrefix = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_DATA_PREFIX);
        String filePath = bdfPrefix + bdfPath;
        Path path = Paths.get(filePath);  // 转换为 Path 对象

        // 检查文件是否存在
        if (!Files.exists(path)) {
            log.error("文件不存在，零件id: {}", id);
            throw new BaseException("文件不存在，零件id: " + id);
        }
        // 删除文件
        int deleteCount = -1;
        int deletedCardCount = -1;
        try {
            // 删除卡片
            deletedCardCount = deleteCards(id);
            deleteCount = baseMapper.deleteById(id);
            Files.delete(path);
        } catch (Exception e) {
            log.error("文件删除失败，零件id: {}", id, e);
            throw new BaseException("文件删除失败，零件id: " + id);  // 重新抛出异常
        }
        if (deleteCount <= 0) {
            log.error("删除失败，零件id: {}", id);
            throw new BaseException("删除失败，零件id: " + id);
        }
        return ("成功删除" + deleteCount + " 条零件数据, " + deletedCardCount + " 条相关卡片数据");
    }

    @Override
    public List<IsfdModelManagementPartVo> componentCheckImport(MultipartFile multipartFile, String modelNumber, String batchNumber, String sectionNumber) {
        // 强度数模清单校验
        if (!isfdModelManagementOriginalPartConfig.checkStrengthBomImport(modelNumber, batchNumber)) {
            throw new BaseException("请先到「标准装机清单」中选择该机型(" + modelNumber + ")及批次(" + batchNumber + ")数据生成”强度数模清单“。");
        }
        //压缩文件原名
        String compressFileName = multipartFile.getOriginalFilename();
        //获取文件名
        String fileName = StringUtils.substringBeforeLast(compressFileName, ".");
        //获取文件后缀
        String fileSuffix = StringUtils.substringAfterLast(compressFileName, ".");

        //multipartFile 转file
        File file = FileUtils.multiPartFileToFile(multipartFile);

        List<String> allPath = null;
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        try {
            String tempPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
                CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
            if (StringUtils.isBlank(tempPath)) {
                throw new BaseException("字典中没有找到文件存储地址的相关配置。");
            }
            IsfdModelManagementPartBo sectionPartPo = new IsfdModelManagementPartBo();
            sectionPartPo.setModelNumber(modelNumber);
            sectionPartPo.setBatchNumber(batchNumber);
            sectionPartPo.setSectionNumber(sectionNumber);
            sectionPartPo.setFileLevel(PartFileLevelEnum.SECTION.getValue());
            List<IsfdModelManagementPartVo> sectionPartVoList = this.queryList(sectionPartPo);
            String modelAndSectionPath = null;
            String modelIndex = null;
            String sectionIndex = null;
            String sortie = null;
            if (!CollectionUtils.isEmpty(sectionPartVoList)) {
                IsfdModelManagementPartVo isfdModelManagementPartVo = sectionPartVoList.get(0);
                modelIndex = isfdModelManagementPartVo.getModelIndex();
                sectionIndex = isfdModelManagementPartVo.getSectionIndex();
                sortie = isfdModelManagementPartVo.getSortie();

                if (StringUtils.isNotBlank(sortie)) {
                    modelAndSectionPath = modelNumber + "_" + sortie + "/" + sectionNumber;
                } else {
                    modelAndSectionPath = modelNumber + "/" + sectionNumber;
                }
            } else {
                modelAndSectionPath = modelNumber + "/" + sectionNumber;
                // 如果没有 整机导入过，模拟一下机型索引，部段索引以及 架次
                modelIndex = modelNumber + "/" + DEFAULT_MODEL;
                sectionIndex = modelAndSectionPath + "/" + DEFAULT_SECTION;
            }

            // 临时文件目录
            String rebuildTempPath = RegexMatcher.getDataPrePath(tempPath, batchNumber) + "/" + modelAndSectionPath;
            File tempPathDir = new File(rebuildTempPath);
            if (!tempPathDir.exists()) {
                tempPathDir.mkdirs();
            }

            //1.解压文件，解析出总的List<Path> allPath
            if (fileSuffix.equalsIgnoreCase(CompressionTypeEnum.ZIP.getValue())) {
                allPath = CompressUtils.extractZipReturnPathList(file, tempPathDir, System.getProperty("sun.jnu.encoding"), Boolean.TRUE);
            } else if (fileSuffix.equalsIgnoreCase(CompressionTypeEnum.RAR.getValue())) {
                allPath = CompressUtils.extractRarReturnPathList(file, tempPathDir, Boolean.TRUE);
            } else {
                throw new BaseException("不支持该压缩文件类型，请确认是导入压缩包类型后再试。");
            }
            if (CollectionUtils.isEmpty(allPath)) {
                throw new BaseException("解压失败");
            }

            //2.校验机型、批次和部段 并进行过滤
            List<String> newAllPath = componentCheckAndFilterPath(modelNumber, batchNumber, sectionNumber, allPath, tempPath);

            //3.找组件索引文件
            List<String> resultList = null;
            Path componentIndexPath = null;
            for (String partPath : newAllPath) {
                Path componentIndexPathWithTemp = Paths.get(partPath);
                String partName = componentIndexPathWithTemp.getFileName().toString();
                if (partName.startsWith(fileName)) {
                    resultList = extractLinesStarting(partPath, tempPath);
                    if (CollectionUtils.isNotEmpty(resultList)) {
                        componentIndexPath = Paths.get(partPath);
                        break;
                    }
                }
            }
            if (CollectionUtils.isEmpty(resultList) && componentIndexPath == null) {
                throw new BaseException("组件索引文件不存在，请确认后重试！");
            }

            String componentIndex = modelAndSectionPath + "/" + fileName + "/" + componentIndexPath.getFileName().toString();

            //4.封装partVoList
            List<IsfdModelManagementPartIndexPathListDealVo> dealVoList = new ArrayList<>();
            // 把索引加进去
            resultList.add(componentIndex);
            for (String partIndex : resultList) {
                //获取文件名
                Path partIndexPath = null;
                if (StringUtils.isBlank(sortie)) {
                    partIndexPath = Paths.get(RegexMatcher.getDataPrePath(tempPath, batchNumber) + File.separator +
                        RegexMatcher.reBuildIndexPath(batchNumber + "/" + partIndex, modelNumber));
                } else {
                    partIndexPath = Paths.get(RegexMatcher.getDataPrePath(tempPath, batchNumber) + File.separator +
                        RegexMatcher.replaceModelAndSortie(partIndex, modelNumber, sortie));
                }

                String partName = partIndexPath.getFileName().toString();
                String[] partNumberAndVersion = RegexMatcher.getPartNumber(partName);
                String partNumber = partNumberAndVersion[0];
                String versionNumber = partNumberAndVersion[1];

                //获取组件编号
                String[] componentIndexPaths = partIndex.split("/");
                String sectionNumberTemp = componentIndexPaths[1];
                //导入的组件 是否 在当前选中的部段下，如果不是的话，不能导入
                if (!sectionNumber.equals(sectionNumberTemp)) {
                    throw new BaseException("当如的组件应该属于：" + sectionNumberTemp + "部段，而不是属于：" + sectionNumber + "部段，请确认后重试！");
                }
                String componentNumber = componentIndexPaths[2];
                //根据零件名称查询文件是否存在
                IsfdModelManagementPartVo partVo = getUniquePartVo(modelNumber, batchNumber, sectionNumber, componentNumber, partName);
                if (partVo == null) {
                    partVo = new IsfdModelManagementPartVo();
                    partVo.setModelNumber(modelNumber);
                    partVo.setSortie(sortie);
                    partVo.setBatchNumber(batchNumber);
                    partVo.setSectionNumber(sectionNumber);
                    partVo.setComponentNumber(componentNumber);
                    partVo.setPartName(partName);
                    partVo.setPartNumber(partNumber);
                    partVo.setFileSize(Files.size(partIndexPath));
                    partVo.setModelIndex(RegexMatcher.reBuildIndexPath(batchNumber + "/" + modelIndex, modelNumber));
                    partVo.setSectionIndex(RegexMatcher.reBuildIndexPath(batchNumber + "/" + sectionIndex, modelNumber));
                    partVo.setComponentIndex(RegexMatcher.reBuildIndexPath(batchNumber + "/" + componentIndex, modelNumber));
                    partVo.setIndexPath(RegexMatcher.reBuildIndexPath(batchNumber + "/" + partIndex, modelNumber));
                    partVo.setFileName(partName);
                    partVo.setFileLevel(PartFileLevelEnum.COMPONENT.getValue());
                    partVo.setVersionNumber(versionNumber);
                    //设置 文件类型
                    if (partName.equals(componentIndexPath.getFileName().toString())) {
                        partVo.setFileType(RegexMatcher.matchesPartFileType(partNumber, resultList).getValue());
                    } else {
                        partVo.setFileType(RegexMatcher.matchesPartFileType(partNumber, null).getValue());
                    }

                    partVo.setFileParsingStatus(FileParsingStatusEnum.NOT_EXIST.getValue());
                    partVo.setImportOperationTags(ImportOperationTagsEnum.ABLE_IMPORT.getValue());
                } else {
                    // 文件大小展示当前 导入文件大小
                    partVo.setFileSize(Files.size(partIndexPath));
                    partVo.setSortie(sortie);
                    partVo.setFileParsingStatus(FileParsingStatusEnum.EXIST.getValue());
                    partVo.setImportOperationTags(ImportOperationTagsEnum.WAIT_FLAG.getValue());
                }

                // 查询 原始装机零件
                initOriginalPartInfo(modelNumber, batchNumber, sectionNumber, partNumber, versionNumber, partVo, dealVoList);
            }

            // 5. 封装统计导入数量是否和原始清单匹配
            for (IsfdModelManagementPartIndexPathListDealVo dealVo : dealVoList) {
                List<IsfdModelManagementPartVo> innerPartVo = dealVo.getPartVoList();
                int importCount = innerPartVo.size();
                Long originalImportCount = dealVo.getOriginalImportCount();
                if (importCount != originalImportCount.intValue()) {
                    for (IsfdModelManagementPartVo p : innerPartVo) {
                        if (OriginalPartExitCchekEnum.EXIT.getValue().equals(p.getExitCheck())) {
                            p.setCountCheck(OriginalPartCountCchekEnum.NOT_MATCH.getValue());
                            p.setImportCount((long) importCount);
                            p.setOriginalImportCount(originalImportCount);
                        }
                    }
                }
                partVoList.addAll(innerPartVo);
            }
            return partVoList;
        } catch (Exception e) {
            log.error("解压失败", e);
            if (e instanceof BaseException) {
                throw (BaseException) e;
            }
            throw new BaseException("解压失败");
        } finally {
            if (file != null) {
                file.delete();
            }
        }
    }

    /**
     * 封装原始清单数据
     */
    private void initOriginalPartInfo(String modelNumber, String batchNumber, String sectionNumber, String partNumber, String versionNumber,
                                      IsfdModelManagementPartVo partVo,
                                      List<IsfdModelManagementPartIndexPathListDealVo> dealVoList) {
        String originalPartNumber = StringUtils.substringBeforeLast(partNumber, ".");
        List<IsfdDetailOriginalV2BomVo> isfdDetailOriginalV2BomVoList = findOriginalPart(modelNumber, batchNumber, sectionNumber, originalPartNumber);

        if (CollectionUtils.isEmpty(isfdDetailOriginalV2BomVoList)) {
            partVo.setExitCheck(OriginalPartExitCchekEnum.NOT_EXIT.getValue());
        } else {
            // 检查是否版本匹配
            Set<String> originalVersionSet = isfdDetailOriginalV2BomVoList.stream().map(IsfdDetailOriginalV2BomVo::getVersion).collect(Collectors.toSet());
            if (!originalVersionSet.contains(versionNumber)) {
                partVo.setVersionCheck(OriginalPartVersionCchekEnum.NOT_MATCH.getValue());
                partVo.setOriginalVersion(String.join(",", originalVersionSet));
            }
            IsfdDetailOriginalV2BomVo isfdDetailOriginalV2BomVo = isfdDetailOriginalV2BomVoList.get(0);
            partVo.setName(isfdDetailOriginalV2BomVo.getName());
            partVo.setAmount(Long.valueOf(isfdDetailOriginalV2BomVo.getCnt()));
            partVo.setUnitWeight(StringUtils.isNotBlank(isfdDetailOriginalV2BomVo.getWeight()) ?
                Double.parseDouble(isfdDetailOriginalV2BomVo.getWeight()) : null);
            partVo.setMaterial(isfdDetailOriginalV2BomVo.getMaterialCode());
        }

        // 封装返回对象
        Optional<IsfdModelManagementPartIndexPathListDealVo> optional = dealVoList.stream().filter(d -> d.getOriginalPartNumber().equals(originalPartNumber)).findFirst();
        if (optional.isPresent()) {
            optional.get().getPartVoList().add(partVo);
        } else {
            List<IsfdModelManagementPartVo> innerList = new ArrayList<>();
            innerList.add(partVo);
            IsfdModelManagementPartIndexPathListDealVo dealVo = new IsfdModelManagementPartIndexPathListDealVo();
            dealVo.setOriginalPartNumber(originalPartNumber);
            // 如果原始装机找不到零件，默认给0L
            dealVo.setOriginalImportCount(OriginalPartExitCchekEnum.EXIT.getValue().equals(partVo.getExitCheck()) ? Long.valueOf(isfdDetailOriginalV2BomVoList.get(0).getCnt()) : 0L);
            dealVo.setPartVoList(innerList);
            dealVoList.add(dealVo);
        }
    }

    @Override
    public IsfdModelManagementConfirmImportPartVo componentConfirmImport(List<IsfdModelManagementPartBo> boList, LoginUser loginUser) {
        List<IsfdModelManagementPartVo> partVoList = new ArrayList<>();
        Long deptId = loginUser.getDeptId();
        Long userId = loginUser.getUserId();
        long importNumber = 0;
        long updatedImportNumber = 0;
        long notImportNumber = 0;
        long failImportNumber = 0;

        // 筛选出 part类型的数据
        List<IsfdModelManagementPartBo> resultPartBoList = boList.stream().filter(bo -> PartFileTypeEnum.checkPartAndFastener(bo.getFileType())).toList();
        if (CollectionUtils.isEmpty(resultPartBoList)) {
            throw new BaseException("没有可导入的零件数据，请确认后重试！");
        }

        // 查询 机型
        IsfdModelManagementPartBo brotherBo = resultPartBoList.get(0);
        String modelNumber = brotherBo.getModelNumber();
        String modelName = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, null, null).getMark();

        // 查询 批次
        String batchNumber = brotherBo.getBatchNumber();
        String batchName = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, null).getMark();

        // 查询 机型
        String sectionNumber = brotherBo.getSectionNumber();
        String sectionName = iIsfdModelManagementStructureDefinitionTreeService.queryOneByQueryIndex(modelNumber, batchNumber, sectionNumber).getMark();


        String tempPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_TEMP_PREFIX);
        String targetPath = iSysDictDataService.selectDictValueByTypeAndLabel(CommonConstant.SYS_COMMON_DICT_TYPE,
            CommonConstant.MODEL_MANAGEMENT_PART_DATA_PREFIX);
        if (StringUtils.isBlank(tempPath) || StringUtils.isBlank(targetPath)) {
            throw new BaseException("字典中没有找到文件存储地址的相关配置。");
        }

        IsfdModelManagementConfirmImportPartVo resultVo = new IsfdModelManagementConfirmImportPartVo();
        for (IsfdModelManagementPartBo bo : resultPartBoList) {
            // 1. 筛选出不需要入库的 导入操作标记
            // WAIT_FLAG(1, "待标记"),ABLE_IMPORT(2, "可导入"),NOT_IMPORT(3, "不导入"),UPDATED(4, "已修改") 中
            // WAIT_FLAG 和 NOT_IMPORT 直接修改状态返回给前端
            Integer importOperationTags = bo.getImportOperationTags();
            if (ImportOperationTagsEnum.WAIT_FLAG.getValue().equals(importOperationTags) ||
                ImportOperationTagsEnum.NOT_IMPORT.getValue().equals(importOperationTags)) {
                IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
                notImportNumber++;
                vo.setImportResultStatus(ImportResultStatusEnum.NOT_IMPORT.getValue());
                partVoList.add(vo);
                continue;
            }

            // 2.判断修改的零件号和版本号是否已存在
            String partNumber = bo.getPartNumber();
            String versionNumber = bo.getVersionNumber();
            String partName = partNumber + "_" + versionNumber + ".bdf";
            IsfdModelManagementPartVo targetVo = getUniquePartVo(bo.getModelNumber(), bo.getBatchNumber(), bo.getSectionNumber(), bo.getComponentNumber(), partName);
            if (targetVo != null && !targetVo.getId().equals(bo.getId())) {
                log.error("导入失败，零件号和版本号与数据库数据重名！");
                IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
                failImportNumber++;
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_FAIL.getValue());
                partVoList.add(vo);
                continue;
            }

            // 3. 查询出机型名称、批次名称和部段名称
            bo.setModelName(modelName);
            bo.setBatchNumber(batchName);
            bo.setSectionName(sectionName);

            IsfdModelManagementPartVo vo = MapstructUtils.convert(bo, IsfdModelManagementPartVo.class);
            try {
                // 4. 写入磁盘文件，把临时目录下的文件 移动 到最终目录下
                IsfdModelManagementPart po = MapstructUtils.convert(bo, IsfdModelManagementPart.class);
                po.setPartName(partName);
                String indexPath = bo.getIndexPath();
                po.setIndexPath(StringUtils.substringBeforeLast(indexPath, "/") + "/" + po.getPartName());
                String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, batchNumber, indexPath, bo.getSortie());
                String newIndexPath = RegexMatcher.getDataPath(targetPath, batchNumber, po.getIndexPath());
                FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);
                if (StringUtils.isNotBlank(bo.getComponentIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.COMPONENT.getValue())
                    && bo.getComponentIndex().equals(bo.getIndexPath())) {
                    po.setComponentIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getSectionIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.SECTION.getValue())
                    && bo.getSectionIndex().equals(bo.getIndexPath())) {
                    po.setSectionIndex(po.getIndexPath());
                }
                if (StringUtils.isNotBlank(bo.getModelIndex())
                    && bo.getFileLevel().equals(PartFileLevelEnum.MODEL.getValue())
                    && bo.getModelIndex().equals(bo.getIndexPath())) {
                    po.setModelIndex(po.getIndexPath());
                }
                po.setPartNumber(partNumber);
                po.setVersionNumber(versionNumber);
                po.setFileName(partName);
                po.setCreateDept(deptId);
                // 5. 存入DB
                if (bo.getId() != null) {
                    po.setUpdateBy(userId);
                    baseMapper.updateById(po);
                } else {
                    po.setCreateBy(userId);
                    po.setUpdateBy(userId);
                    baseMapper.insert(po);
                }

                //6. 返回封装vo
                vo = MapstructUtils.convert(po, IsfdModelManagementPartVo.class);
                if (ImportOperationTagsEnum.ABLE_IMPORT.getValue().equals(importOperationTags)) {
                    importNumber++;
                    vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_SUCCESS.getValue());
                } else if (ImportOperationTagsEnum.UPDATED.getValue().equals(importOperationTags)) {
                    vo.setImportResultStatus(ImportResultStatusEnum.UPDATED_IMPORT.getValue());
                    updatedImportNumber++;
                } else {
                    log.error("当前数据未定义操作类型，partName是:{} , indexPath是:{}", bo.getPartName(), bo.getIndexPath());
                }
                partVoList.add(vo);
            } catch (Exception e) {
                vo.setImportResultStatus(ImportResultStatusEnum.IMPORT_FAIL.getValue());
                failImportNumber++;
                partVoList.add(vo);
                log.error("导入失败", e);
            }
        }
        resultVo.setPartVoList(partVoList);
        resultVo.setImportNumber(importNumber);
        resultVo.setFailImportNumber(failImportNumber);
        resultVo.setNotImportNumber(notImportNumber);
        resultVo.setUpdatedImportNumber(updatedImportNumber);

        // 处理非零件的数据，索引、拓展
        List<IsfdModelManagementPartBo> resultOtherBoList = boList.stream().filter(bo -> !PartFileTypeEnum.checkPartAndFastener(bo.getFileType())).toList();
        for (IsfdModelManagementPartBo bo : resultOtherBoList) {
            IsfdModelManagementPart po = MapstructUtils.convert(bo, IsfdModelManagementPart.class);
            String indexPath = bo.getIndexPath();
            String oldIndexPath = RegexMatcher.rebuildOldDataPath(tempPath, batchNumber, indexPath, bo.getSortie());
            String newIndexPath = RegexMatcher.getDataPath(targetPath, batchNumber, indexPath);
            FileUtils.copyOrMoveFile(oldIndexPath, newIndexPath, Boolean.TRUE);
            po.setVersionNumber(null);
            po.setPartNumber(null);
            po.setCreateDept(deptId);
            if (bo.getId() != null) {
                po.setUpdateBy(userId);
                baseMapper.updateById(po);
            } else {
                po.setCreateBy(userId);
                po.setUpdateBy(userId);
                baseMapper.insert(po);
            }
        }


        return resultVo;
    }

    private Integer deleteCards(Long partId) {
        List<IsfdModelManagementCard> cardList = isfdModelManagementCardMapper.selectList(Wrappers.<IsfdModelManagementCard>lambdaQuery()
            .eq(IsfdModelManagementCard::getPartId, partId));
        if (cardList.isEmpty()) {
            log.error("未找到相关零件卡片！partId: {}", partId);
            return 0;
        }
        return isfdModelManagementCardMapper.deleteBatchIds(cardList);
    }

}
